package pl.bizuteria.sklep.admin.client.ui.product;

import java.util.List;

import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.AbstractHasData;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.ColumnSortEvent.AsyncHandler;
import com.google.gwt.user.cellview.client.ColumnSortList;
import com.google.gwt.user.cellview.client.Header;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.requestfactory.shared.EntityProxy;

public abstract class AbstractProxyListView<P extends EntityProxy> extends
		Composite implements IProxyListView<P> {

	private static AbstractProxyListViewUiBinder uiBinder = GWT
			.create(AbstractProxyListViewUiBinder.class);

	interface AbstractProxyListViewUiBinder extends
			UiBinder<Widget, AbstractProxyListView> {
	}

	@UiField(provided = true)
	SimplePager pager;

	public AbstractProxyListView(ProductButtonView productButtonView) {
		this.productButtonView = productButtonView;

		createTable();

		createPager();

		createSortHanlder();
		// setElement(uiBinder.createAndBindUi(this));
		initWidget(uiBinder.createAndBindUi(this));
		// trzeba jeszcze raz ustawic page size bo jest resetowany w initWidget
		table.setPageSize(2);
	}

	private void createSortHanlder() {
		AsyncHandler asyncHandler = new ColumnSortEvent.AsyncHandler(table);
		table.addColumnSortHandler(asyncHandler);
	}

	private void createPager() {
		pager = new SimplePager();
		// pager = new SimplePager(TextLocation.CENTER, null, false, 0,
		// true);
		pager.setDisplay(table);
	}

	private void createTable() {
		// nie wiadomo dlaczego ale ten page size pozniej jest resetowany przy
		// initWidget....
		table = new CellTable<P>(2);

		CheckboxCell headerCheckbox = new CheckboxCell() {
			/**
			 * An html string representation of a checked input box.
			 */
			private final SafeHtml INPUT_CHECKED = SafeHtmlUtils
					.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
			/**
			 * An html string representation of an unchecked input box.
			 */
			private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils
					.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");

			@Override
			public void render(Context context, Boolean value,
					SafeHtmlBuilder sb) {
				if (value != null && value) {
					sb.append(INPUT_CHECKED);
				} else {
					sb.append(INPUT_UNCHECKED);
				}
			}
		};

		Column<P, Boolean> checkBoxColumn = createCheckBoxColumn();
		Header<Boolean> checkBoxHeader = new Header<Boolean>(headerCheckbox) {

			@Override
			public Boolean getValue() {
				for (P item : table.getVisibleItems()) {
					if (!table.getSelectionModel().isSelected(item)) {
						return false;
					}
				}
				return table.getVisibleItems().size() > 0;
			}

		};

		checkBoxHeader.setUpdater(new ValueUpdater<Boolean>() {

			@Override
			public void update(Boolean value) {
				// Window.alert("updating`123 = " + value);
				List<P> visibleItems = table.getVisibleItems();
				// Window.alert("Visible items = " + visibleItems);
				for (P visibleItem : visibleItems) {
					// Window.alert("selecting object = " + visibleItem + " " +
					// value);
					table.getSelectionModel().setSelected(visibleItem, value);
				}
				// Window.alert("selection model = " +
				// table.getSelectionModel());

			}
		});

		table.addColumn(checkBoxColumn, checkBoxHeader);

		table.setColumnWidth(checkBoxColumn, "10%");

		addColumns(table);

	}

	protected abstract void addColumns(CellTable<P> table);

	@UiField
	Button createButton;

	@UiField
	Button deleteButton;

	@UiField(provided = true)
	ProductButtonView productButtonView;

	@UiField(provided = true)
	CellTable<P> table;

	@Override
	public AbstractHasData<P> asHasData() {
		return table;
	}

	@Override
	public Widget asWidget() {
		return this;
	}

	protected pl.bizuteria.sklep.admin.client.ui.product.IProxyListView.Delegate delegate;

	@Override
	public void setDelegate(Delegate delegate) {
		this.delegate = delegate;
	}

	@UiHandler("createButton")
	public void createClicked(ClickEvent clickEvent) {
		delegate.createClicked();
	}

	@UiHandler("deleteButton")
	public void deleteClicked(ClickEvent clickEvent) {
		delegate.deleteClicked();
	}

	protected Column<P, Boolean> createCheckBoxColumn() {

		Column<P, Boolean> checkBoxColumn = new Column<P, Boolean>(
				new CheckboxCell(false, false)) {
			@Override
			public Boolean getValue(P object) {
				boolean selected = table.getSelectionModel().isSelected(object);
				// System.out.println("CheckBoxValue = " + selected);
				return selected;
				/*
				 * if(object instanceof EaringProxy){ EaringProxy earingProxy =
				 * (EaringProxy) object;
				 * System.out.println("checkBoxColumn getValue " +
				 * earingProxy.getName()); } else {
				 * System.out.println("(2) checkBoxColumn getValue " + object );
				 * }
				 * 
				 * return false;
				 */
			}
		};

		checkBoxColumn.setFieldUpdater(new FieldUpdater<P, Boolean>() {

			@Override
			public void update(int index, P object, Boolean value) {
				table.getSelectionModel().setSelected(object, value);
			}
		});

		return checkBoxColumn;

	}

	@Override
	public ColumnSortList getColumnSortList() {
		return table.getColumnSortList();
	}

}
